package com.dmz.workflow.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dmz.workflow.base.BaseServiceImpl;
import com.dmz.workflow.constant.CommonConstants;
import com.dmz.workflow.constant.ExceptionMessageConstants;
import com.dmz.workflow.constant.ProcessDefinitionConstants;
import com.dmz.workflow.dao.ApprovalNodeMapper;
import com.dmz.workflow.dao.FlowableFormMapper;
import com.dmz.workflow.dao.FormGroupMapper;
import com.dmz.workflow.dao.FormPermiMapper;
import com.dmz.workflow.dto.ApprovalNode;
import com.dmz.workflow.dto.BranchNode;
import com.dmz.workflow.entity.FormGroup;
import com.dmz.workflow.entity.FormInfo;
import com.dmz.workflow.entity.FormPermi;
import com.dmz.workflow.entity.ProcessJson;
import com.dmz.workflow.service.FlowableFormService;
import com.dmz.workflow.service.WorkflowFormPermiService;
import com.dmz.workflow.service.WorkflowProcessJsonService;
import com.dmz.workflow.util.ElExpressionUtil;
import com.dmz.workflow.util.ObjectUtils;
import com.dmz.workflow.util.ProcessModelFactory;
import com.dmz.workflow.util.SnowFlakeUtils;
import com.dmz.workflow.vo.*;
import com.echronos.commons.Result;
import com.echronos.commons.enums.ErrorMsgEnum;
import com.echronos.commons.model.RequestUser;
import com.echronos.commons.utils.RequestUserUtils;
import com.echronos.system.feign.IMemberFeign;
import com.echronos.system.resp.MemberAllInfoResp;
import com.echronos.workflow.entity.*;
import com.echronos.workflow.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngines;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.validation.ProcessValidator;
import org.flowable.validation.ProcessValidatorFactory;
import org.flowable.validation.ValidationError;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 表单流程service
 */
@Slf4j
@Service
public class FlowableFormServiceImpl extends BaseServiceImpl<FlowableFormMapper, FormInfo> implements FlowableFormService {

    private static ProcessModelFactory processModel = new ProcessModelFactory();

    private String title;
    private List<SequenceFlow> sequenceFlows;

    @Autowired
    private FlowableFormMapper flowableFormMapper;

    @Autowired
    private FormGroupMapper formGroupMapper;

    @Autowired
    private FormPermiMapper formPermiMapper;

    @Autowired
    private IMemberFeign memberFeign;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ApprovalNodeMapper approvalNodeMapper;

    @Autowired
    private WorkflowProcessJsonService workflowProcessJsonService;

    @Autowired
    private WorkflowFormPermiService workflowFormPermiService;

    /**
     * 查询表单列表
     * 1.分权限展示，先排除是否为管理员，然后分人去取公司，部门，角色，进行判断是否包含
     * 2.先查询个人的角色部门公司，利用sql是否包含其中
     * 这里还需要将Vo转成实体进行数据操作
     **/
    @Override
    public IPage<FormInfoGroupVo> listProcess(String keyword, Integer endpoint) throws RuntimeException {
        RequestUser user = RequestUserUtils.getUser();
        Integer memberId = user.getMemberId();
        Integer companyId = user.getCompanyId();
        Map<String, Object> queryMap = new HashMap<>();
        IPage<FormInfoGroupVo> formInfoGroupVoPage = new Page<>();
        List<FormInfoGroupVo> formInfoGroupVos = new ArrayList<>();
        List<FormGroupVo> formGroupVos = formGroupMapper.selectListByCompanyId(companyId);
        if (CommonConstants.FRONT_ENDPOINT.equals(endpoint)) {
            MemberAllInfoResp memberAllInfoResp = memberFeign.queryListUserInfo(memberId);
            if (ObjectUtil.isNotNull(memberAllInfoResp)) {
                for (FormGroupVo formGroupVO : formGroupVos) {
                    //获取部门
                    List<Integer> deptId = memberAllInfoResp.getDeptId();
                    queryMap.put("deptId", deptId);
                    //获取角色
                    List<Integer> roleId = memberAllInfoResp.getRoleId();
                    queryMap.put("roleId", roleId);
                    queryMap.put("memberId", Collections.singletonList(memberId));
                    queryMap.put("companyId", Collections.singletonList(companyId));
                    queryMap.put("keyword", keyword);
                    queryMap.put("endpoint", endpoint);
                    queryMap.put("groupId", Collections.singletonList(formGroupVO.getId()));
                    FormInfoGroupVo formInfoGroupVo = encapsulateFormInfoGroupVo(formGroupVO);
                    List<FormInfoVo> formInfoVos = flowableFormMapper.queyUserList(queryMap);
                    if (StringUtils.isNotEmpty(keyword) && ObjectUtils.isNotEmpty(formInfoVos)) {
                        formInfoGroupVo.setFromInfo(formInfoVos);
                        formInfoGroupVos.add(formInfoGroupVo);
                    }
                    if (StringUtils.isEmpty(keyword)) {
                        formInfoGroupVo.setFromInfo(formInfoVos);
                        formInfoGroupVos.add(formInfoGroupVo);
                    }
                }
            }
        } else {
            List<FormInfo> formInfos = queryCurrentCompanyAllProcesses(companyId);
            if (ObjectUtils.isNotEmpty(formInfos)) {
                for (FormGroupVo formGroupVo : formGroupVos) {
                    FormInfoGroupVo formInfoGroupVo = encapsulateFormInfoGroupVo(formGroupVo);
                    List<FormInfoVo> formInfoVOS = new ArrayList<>();
                    List<Integer> formInfoIds = new ArrayList<>();
                    for (FormInfo info : formInfos) {
                        formInfoIds.add(info.getId());
                    }
                    List<FormPermi> formPermis = new ArrayList<>();
                    if (ObjectUtils.isNotEmpty(formInfoIds)) {
                        formPermis = workflowFormPermiService.queryFormPermiName(formInfoIds);
                    }
                    for (FormInfo formInfo : formInfos) {
                        if (formGroupVo.getId().equals(formInfo.getGroupId())) {
                            FormInfoVo formInfoVo = new FormInfoVo();
                            BeanUtils.copyProperties(formInfo, formInfoVo);
                            for (FormPermi formPermi : formPermis) {
                                if (formInfo.getId().equals(formPermi.getInfoId())) {
                                    formInfoVo.setPermiName(formPermi.getPermiName());
                                }
                            }
                            formInfoVOS.add(formInfoVo);
                        }
                    }
                    formInfoGroupVo.setFromInfo(formInfoVOS);
                    formInfoGroupVos.add(formInfoGroupVo);
                }
            } else {
                if (ObjectUtils.isNotEmpty(formGroupVos)) {
                    for (FormGroupVo formGroupVo : formGroupVos) {
                        FormInfoGroupVo formInfoGroupVo = encapsulateFormInfoGroupVo(formGroupVo);
                        formInfoGroupVo.setFromInfo(new ArrayList<>());
                        formInfoGroupVos.add(formInfoGroupVo);
                    }
                }
            }
        }
        formInfoGroupVoPage.setRecords(formInfoGroupVos);
        return formInfoGroupVoPage;
    }

    @Override
    public List<String> queryValidProcessNames() {
        RequestUser user = RequestUserUtils.getUser();
        Integer companyId = user.getCompanyId();
        List<FormInfo> formInfos = queryCurrentCompanyAllProcesses(companyId);
        List<String> processNameList = new ArrayList<>();
        if (!ObjectUtils.validateCollectionIsEmpty(formInfos)) {
            for (FormInfo formInfo : formInfos) {
                processNameList.add(formInfo.getName());
            }
        }
        return processNameList;
    }

    private FormInfoGroupVo encapsulateFormInfoGroupVo(FormGroupVo formGroupVo) {
        FormInfoGroupVo formInfoGroupVo = new FormInfoGroupVo();
        formInfoGroupVo.setGroupId(formGroupVo.getId());
        formInfoGroupVo.setGroupIsDeleted(formGroupVo.getIsDeleted());
        formInfoGroupVo.setGroupName(formGroupVo.getName());
        formInfoGroupVo.setGroupCreateTime(formGroupVo.getCreateTime());
        formInfoGroupVo.setGroupCreateUser(formGroupVo.getCreateUser());
        formInfoGroupVo.setGroupUpdateUser(formGroupVo.getUpdateUser());
        formInfoGroupVo.setGroupUpdateTime(formGroupVo.getUpdateTime());
        formInfoGroupVo.setGroupOrd(formGroupVo.getOrd());
        formInfoGroupVo.setGroupStatus(formGroupVo.getStatus());
        return formInfoGroupVo;
    }

    @Override
    public void updateFromSort(List<FormInfoVo> infoVos) {
        //获取当前用户
        RequestUser user = RequestUserUtils.getUser();
        infoVos.forEach(formInfoVO -> {
            formInfoVO.setUpdateUser(user.getMemberId());
            formInfoVO.setUpdateTime(LocalDateTime.now());
            formInfoVO.setCompanyId(user.getCompanyId());
        });
        flowableFormMapper.updateFromSort(infoVos);
    }

    @Override
    public ProcessSetupVo queryFormById(String id) {
        FormInfoVo flowableForm = flowableFormMapper.queryWorkflowById(id);
        ProcessJsonVo processJsonVO = new ProcessJsonVo();
        ProcessJson processJson = workflowProcessJsonService.getProcessJsonByProcessDefinitionId(id);
        BeanUtils.copyProperties(processJson, processJsonVO);
        List<FormPermiVo> formPermiVos = formPermiMapper.selectListFormPermById(id);
        FormGroup formGroup = formGroupMapper.selectById(flowableForm.getGroupId());
        ProcessSetupVo setupVo = new ProcessSetupVo();
        setupVo.setFormGroup(formGroup);
        setupVo.setFormInfoVO(flowableForm);
        setupVo.setFormPermiVOS(formPermiVos);
        setupVo.setProcessJsonVO(processJsonVO);
        return setupVo;
    }

    @Override
    public int queryCurrentCompanyValidProcessName(Integer companyId, String formName, String processDefinitionId) {
        LambdaQueryWrapper<FormInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FormInfo::getName, formName).eq(FormInfo::getCompanyId, companyId);
        if (ObjectUtils.isNotEmpty(processDefinitionId)) {
            lambdaQueryWrapper.ne(FormInfo::getProcessDefinitionId, processDefinitionId);
        }
        return flowableFormMapper.selectCount(lambdaQueryWrapper);
    }

    @Override
    public FormInfo queryFormInfoByProcessDefinitionId(String processDefinitionId) {
        LambdaQueryWrapper<FormInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FormInfo::getProcessDefinitionId, processDefinitionId)
                .ne(FormInfo::getIsDeleted, CommonConstants.DATA_DELETED_STATUS);
        return flowableFormMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public List<FormInfo> queryCurrentCompanyAllProcesses(Integer companyId) {
        LambdaQueryWrapper<FormInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FormInfo::getCompanyId, companyId)
                .ne(FormInfo::getIsDeleted, CommonConstants.DATA_DELETED_STATUS);
        return flowableFormMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 修改流程解决思路
     * 修改，ech_workflow_form_info，
     * 删除所有关联流程定义
     * 再次新增流程
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> updateFormById(FormInfoVo formInfoVO) {
        RequestUser user = RequestUserUtils.getUser();
        if (queryCurrentCompanyValidProcessName(user.getCompanyId(), formInfoVO.getName(), formInfoVO.getProcessDefinitionId()) > 0) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ExceptionMessageConstants.FORM_NAME_DUPLICATE_MESSAGE);
        }
        //删除之前扩展包数据，查询流程定义key，根据key定义发布新版本流程
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(formInfoVO.getProcessDefinitionId()).singleResult();
        String processKey = processDefinition.getKey();
        flowableFormMapper.deleteFromInfoByWid(formInfoVO.getProcessDefinitionId());
        formPermiMapper.deletePermByWid(formInfoVO.getProcessDefinitionId());
        approvalNodeMapper.deleteProcessByWid(formInfoVO.getProcessDefinitionId());
        //获取当前用户
        if (formInfoVO.getWorkSetModelVo() != null && formInfoVO.getProcessJsonTree() != null) {
            processDefinitionProcessor(formInfoVO, processKey);
        } else {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ExceptionMessageConstants.PROCESS_DEFINITION_OPERATION_MESSAGE);
        }
        return Result.build();
    }

    /**
     * 新增表单
     * 1.先插入表单主表
     * 2.在插入权限表
     * 3.最后插入表单json
     * 4.完成流程设计逻辑判断生成文件
     * 5.自动部署并持久化 流程定义
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<?> saveForm(FormInfoVo flowableForm) {
        RequestUser user = RequestUserUtils.getUser();
        if (queryCurrentCompanyValidProcessName(user.getCompanyId(), flowableForm.getName(), null) > 0) {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ExceptionMessageConstants.FORM_NAME_DUPLICATE_MESSAGE);
        }
        if (flowableForm.getWorkSetModelVo() != null && flowableForm.getProcessJsonTree() != null) {
            String processKey = "PNO-" + SnowFlakeUtils.getFlowIdInstance().nextId();
            processDefinitionProcessor(flowableForm, processKey);
        } else {
            return Result.build(ErrorMsgEnum.NORMAL_ERR.getErrorCode(), ExceptionMessageConstants.PROCESS_DEFINITION_OPERATION_MESSAGE);
        }
        return Result.build();
    }

    private FormInfo saveFormInfo(FormInfoVo flowableForm, RequestUser user, boolean updateOperation, String processDefinitionId, String processDefinitionKey, String formKey) {
        FormInfo formInfo = new FormInfo();
        BeanUtils.copyProperties(flowableForm, formInfo);
        String tenantId = "Ten:" + UUID.randomUUID();
        flowableForm.setTenantId(tenantId);
        formInfo.setLang(CommonConstants.CHINESE_LANGUAGE_MARK);
        formInfo.setTenantId(tenantId);
        formInfo.setFormJson(flowableForm.getFormJson());
        formInfo.setFormKey(formKey);
        formInfo.setCreateUser(user.getId());
        formInfo.setCreateTime(LocalDateTime.now());
        formInfo.setCompanyId(user.getCompanyId());
        formInfo.setSignature(flowableForm.getSignature());
        formInfo.setProcessDefinitionId(processDefinitionId);
        formInfo.setProcessDefinitionKey(processDefinitionKey);
        if (updateOperation) {
            formInfo.setUpdateTime(LocalDateTime.now());
            formInfo.setUpdateUser(user.getId());
        }
        flowableFormMapper.saveForm(formInfo);
        return formInfo;
    }

    private void saveFormPermission(FormInfoVo flowableForm, RequestUser user, Integer formInfoId, String processDefinitionId, String processDefinitionKey) {
        if (flowableForm.getVisible() == null || flowableForm.getVisible().size() <= 0) {
            FormPermi formPermi = new FormPermi();
            formPermi.setIsMark(1);
            formPermi.setPermiName(CommonConstants.COMPANY_DESCRIPTION);
            formPermi.setPermiId(user.getCompanyId());
            formPermi.setCreateUser(user.getId());
            formPermi.setInfoId(formInfoId);
            formPermi.setIsAdmin(0);
            formPermi.setCompanyId(user.getCompanyId());
            formPermi.setProcessDefinitionId(processDefinitionId);
            formPermi.setProcessDefinitionKey(processDefinitionKey);
            formPermiMapper.addFormPermi(formPermi);
        } else {
            List<FormPermiVo> visible = flowableForm.getVisible();
            for (FormPermiVo formPermiVO : visible) {
                FormPermi formPermi = new FormPermi();
                formPermi.setIsMark(formPermiVO.getIsMark());
                formPermi.setPermiName(formPermiVO.getPermiName());
                formPermi.setPermiId(formPermiVO.getPermiId());
                formPermi.setCreateUser(user.getId());
                formPermi.setInfoId(formInfoId);
                formPermi.setIsAdmin(0);
                formPermi.setCompanyId(user.getCompanyId());
                formPermi.setProcessDefinitionId(processDefinitionId);
                formPermi.setProcessDefinitionKey(processDefinitionKey);
                formPermiMapper.addFormPermi(formPermi);
            }
        }
    }

    private ProcessJson saveProcessJson(FormInfoVo flowableForm, RequestUser user, Integer formId, String processDefinitionId, String processDefinitionKey) {
        ProcessJson processJson = new ProcessJson();
        processJson.setName(flowableForm.getName());
        processJson.setCompanyId(user.getCompanyId());
        processJson.setCreationUser(user.getMemberId());
        processJson.setCreationTime(LocalDateTime.now());
        processJson.setIntoId(formId);
        processJson.setProcessJson(flowableForm.getWorkSetModelVo());
        processJson.setProcessJsonTree(flowableForm.getProcessJsonTree());
        processJson.setProcessDefinitionId(processDefinitionId);
        processJson.setProcessDefinitionKey(processDefinitionKey);
        approvalNodeMapper.saveFlowJson(processJson);
        return processJson;
    }

    private void processDefinitionProcessor(FormInfoVo flowableForm, String processKey) {
        RequestUser user = RequestUserUtils.getUser();
        String formKey = flowableForm.getName() + "-" + user.getMemberId() + "-" + user.getCompanyId();
        String processName = flowableForm.getName();
        BpmnModel bpmnModel = new BpmnModel();
        String xmlString = processDefinitionProcessor(bpmnModel, flowableForm, processName, processKey, formKey);
        ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
        ProcessValidator defaultProcessValidator = processValidatorFactory.createDefaultProcessValidator();
        List<ValidationError> validate = defaultProcessValidator.validate(bpmnModel);
        byte[] formJson = flowableForm.getFormJson().getBytes(StandardCharsets.UTF_8);
        ByteArrayInputStream processFormJson = new ByteArrayInputStream(formJson);
        log.info("构建流程图错误信息：" + validate.toString());
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRepositoryService()
                .createDeployment()
                .name(flowableForm.getName())
                .addString(flowableForm.getName() + ".bpmn", xmlString)
                .addInputStream(formKey, processFormJson)
                .deploy();
        ProcessDefinitionQuery query = processEngine.getRepositoryService()
                .createProcessDefinitionQuery()
                .processDefinitionKey(processKey)
                .latestVersion();
        String processDefId = query.singleResult().getId();
        FormInfo formInfo = saveFormInfo(flowableForm, user, false, processDefId, processKey, formKey);
        saveFormPermission(flowableForm, user, formInfo.getId(), processDefId, processKey);
        saveProcessJson(flowableForm, user, formInfo.getId(), processDefId, processKey);
    }

    private String processDefinitionProcessor(BpmnModel bpmnModel, FormInfoVo flowableForm, String processName, String processKey, String formKey) {
        Process process = new Process();
        process.setName(processName);
        process.setId(processKey);
        process.addFlowElement(processModel.getDataObject());
        processNodeJsonToXML(flowableForm.getWorkSetModelVo(), process, formKey);
        bpmnModel.addProcess(process);
        BpmnAutoLayout bpmnLayout = new BpmnAutoLayout(bpmnModel);
        bpmnLayout.execute();
        BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
        byte[] convertToXML = bpmnXMLConverter.convertToXML(bpmnModel);
        return new String(convertToXML, StandardCharsets.UTF_8);
    }

    public void processNodeJsonToXML(String nodeJson, Process process, String formKey) {
        List<ApprovalNode> approvalNodes = JSON.parseArray(nodeJson, ApprovalNode.class);
        for (ApprovalNode approvalNode : approvalNodes) {
            switch (approvalNode.getType()) {
                case ProcessDefinitionConstants.START_NODE:
                    getStartNode(process, approvalNode, formKey);
                    break;
                case ProcessDefinitionConstants.EVENT_NODE:
                    process.addFlowElement(processModel.createEndEvent(approvalNode.getThisId(), "结束"));
                    break;
                case ProcessDefinitionConstants.DUPLICATE_NODE:
                    getCopyNode(process, approvalNode);
                    break;
                case ProcessDefinitionConstants.TERM_NODE:
                    getConditionsNode(process, approvalNode);
                    break;
                default:
                    if (ProcessDefinitionConstants.START_NODE_NAME.equals(approvalNode.getThisId())) {
                        List<SequenceFlow> startTask = new ArrayList<>();
                        approvalNode.getConditions().forEach(conditions -> {
                            SequenceFlow sequenceFlow = processModel.createSequenceFlow(approvalNode.getThisId(), conditions.getNextId(), conditions.getTitle(), null);
                            process.addFlowElement(sequenceFlow);
                            startTask.add(sequenceFlow);
                        });
                        process.addFlowElement(processModel.createInitiator(formKey, startTask));
                        continue;
                    }

                    if (approvalNode.getStatus().equals(ProcessDefinitionConstants.STARTER_SELECTION_MEMBER)) {
                        if (approvalNode.getIsCheckbox().equals(ProcessDefinitionConstants.ONE_PERSON_SELECTED)) {
                            getAssignUelNode(process, formKey, approvalNode);
                        }
                        if (approvalNode.getIsCheckbox().equals(ProcessDefinitionConstants.MULTIPLE_PERSON_SELECTED)) {
                            manyNodes(formKey, approvalNode, process);
                        }
                    }
                    if (approvalNode.getStatus().equals(ProcessDefinitionConstants.ASSIGNED_MEMBER)) {
                        manyNodes(formKey, approvalNode, process);
                    }
                    if (approvalNode.getStatus().equals(ProcessDefinitionConstants.DEPARTMENT_LEADER_MEMBER)) {
                        manyNodes(formKey, approvalNode, process);
                    }
                    if (approvalNode.getStatus().equals(ProcessDefinitionConstants.ROLE_MEMBER)) {
                        manyNodes(formKey, approvalNode, process);
                    }
                    break;
            }
        }
    }

    @Override
    public void removeFormByIds(List<String> processDefinitionIds) {
        if (processDefinitionIds.size() > 0) {
            LambdaUpdateWrapper<FormInfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.in(FormInfo::getProcessDefinitionId, processDefinitionIds);
            FormInfo formInfo = new FormInfo();
            formInfo.setIsDeleted(CommonConstants.DATA_DELETED_STATUS);
            flowableFormMapper.update(formInfo, lambdaUpdateWrapper);
        }
    }

    public void getAssignUelNode(Process process, String formKey, ApprovalNode approvalNode) {
        getSequenceFlow(approvalNode, process);
        process.addFlowElement(processModel.createCounterSignUserTask(approvalNode.getThisId(), title, formKey, sequenceFlows, false));
    }

    public void getConditionsNode(Process process, ApprovalNode approvalNode) {
        getSequenceFlow(approvalNode, process);
        process.addFlowElement(processModel.createExclusiveGateway(approvalNode.getThisId(), "条件网关", sequenceFlows));
    }

    public void getCopyNode(Process process, ApprovalNode approvalNode) {
        getSequenceFlow(approvalNode, process);
        process.addFlowElement(processModel.createServiceTask(approvalNode.getThisId(), title, sequenceFlows));
    }

    public void getStartNode(Process process, ApprovalNode approvalNode, String formKey) {
        getSequenceFlow(approvalNode, process);
        process.addFlowElement(processModel.createStartEvent(approvalNode.getThisId(), "启动流程", formKey, sequenceFlows));
    }

    public void manyNodes(String formKey, ApprovalNode approvalNode, Process process) {
        if (approvalNode.getActivity() != null) {
            switch (approvalNode.getActivity()) {
                case ProcessDefinitionConstants.COUNTER_SIGN:
                    getCountersignNode(formKey, approvalNode, process);
                    break;
                case ProcessDefinitionConstants.OR_SIGN:
                    getOrSignNode(formKey, approvalNode, process);
                    break;
                default:
                    getSuccessivelyNode(formKey, approvalNode, process);
                    break;
            }
        } else {
            getSuccessivelyNode(formKey, approvalNode, process);
        }
    }

    public void getSuccessivelyNode(String formKey, ApprovalNode approvalNode, Process process) {
        getSequenceFlow(approvalNode, process);
        process.addFlowElement(processModel.createCounterSignUserTask(approvalNode.getThisId(), title, formKey, sequenceFlows, true));
    }

    public void getOrSignNode(String formKey, ApprovalNode approvalNode, Process process) {
        getSequenceFlow(approvalNode, process);
        process.addFlowElement(processModel.createOrSignUserTask(approvalNode.getThisId(), title, formKey, sequenceFlows, false));
    }

    public void getCountersignNode(String formKey, ApprovalNode approvalNode, Process process) {
        getSequenceFlow(approvalNode, process);
        process.addFlowElement(processModel.createCounterSignUserTask(approvalNode.getThisId(), title, formKey, sequenceFlows, false));
    }

    private void getSequenceFlow(ApprovalNode approvalNode, Process process) {
        sequenceFlows = new ArrayList<>();
        List<BranchNode> branchNodes = approvalNode.getConditions();
        for (BranchNode branchNode : branchNodes) {
            title = branchNode.getTitle();
            SequenceFlow sequenceFlow;
            if (ObjectUtils.isNotEmpty(branchNode.getCriteria())) {
                String el = ElExpressionUtil.generateElExpression(branchNode.getCriteria());
                log.info("El表达式为：" + el);
                sequenceFlow = processModel.createSequenceFlow(approvalNode.getThisId(), branchNode.getNextId(), branchNode.getTitle(), el);
            } else {
                sequenceFlow = processModel.createSequenceFlow(approvalNode.getThisId(), branchNode.getNextId(), branchNode.getTitle(), null);
            }
            process.addFlowElement(sequenceFlow);
            sequenceFlows.add(sequenceFlow);
        }
    }
}
